package com.example.demoserver.mqtt;

import com.alibaba.druid.sql.dialect.db2.visitor.DB2OutputVisitor;
import com.example.demoserver.entity.InteAppalarm;
import com.example.demoserver.service.*;
import com.example.demoserver.service.impl.InteGatewayServiceImpl;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.mqtt.MqttDecoder;
import io.netty.handler.codec.mqtt.MqttEncoder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;


@Slf4j
@RequiredArgsConstructor
public class TestServer {

    private final InteDatapointService inteDatapointService;

    private final InteGatewayService inteGatewayService;

    private final InteAppstateService inteAppstateService;

    private final InteAppalarmService inteAppalarmService;

    private final InteGatewaylogService inteGatewaylogService;
    private Channel channel;
    // 监听端口号
    int port = 1883;
    // 构建主线程-用于分发socket请求
    static NioEventLoopGroup boosGroup;

    // 构建工作线程-用于处理请求处理
    static NioEventLoopGroup workGroup;

    ServerBootstrap serverBootstrap = new ServerBootstrap();

    public boolean run() {
        try {
            boosGroup = new NioEventLoopGroup(1);
            workGroup = new NioEventLoopGroup();
            serverBootstrap.group(boosGroup, workGroup)
                    .channel(NioServerSocketChannel.class)
                    .childOption(ChannelOption.SO_KEEPALIVE, true)
                    .childOption(ChannelOption.TCP_NODELAY, true)
                    .childOption(ChannelOption.SO_BACKLOG,1024)   //等待队列
                    .childOption(ChannelOption.SO_REUSEADDR, true)   //快速复用
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel socketChannel) throws Exception {
                            // 这个地方注意，如果客户端发送请求体超过此设置值，会抛异常
                            socketChannel.pipeline().addLast(new MqttDecoder(1024 * 1024));
                            socketChannel.pipeline().addLast(MqttEncoder.INSTANCE);
                            // 加载MQTT编解码协议，包含业务逻辑对象
                            socketChannel.pipeline().addLast(new TestMqttHandler(inteDatapointService, inteGatewayService, inteAppstateService, inteAppalarmService, inteGatewaylogService));
                        }
                    });
            serverBootstrap.bind(port).addListener(future -> {
                log.info("服务端成功绑定端口号={}", port);

            });
            //channel = serverBootstrap.bind(port).sync().channel();
            return true;
        } catch (Exception e) {
            boosGroup.shutdownGracefully();
            workGroup.shutdownGracefully();
            log.error("mqttServer启动失败:{}", e);
            LocalDateTime now = LocalDateTime.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            String formatted = now.format(formatter);
            InteAppalarm inteAppalarm = new InteAppalarm();
            inteAppalarm.setAlarminfo("mqttServer启动失败");
            inteAppalarm.setAlarmtime(formatted);
            inteAppalarmService.save(inteAppalarm);
            return false;
        }
    }

    public boolean stop() throws InterruptedException {

        if (workGroup != null && boosGroup != null) {
            boosGroup.shutdownGracefully().sync();
            workGroup.shutdownGracefully().sync();
            if (boosGroup.isShutdown() && workGroup.isShutdown()) {
                return true;
            }
        }
        return false;
    }

}
